package unmsm.fisi.tesis.web.mb;

import java.util.ArrayList;
import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

import org.primefaces.event.CellEditEvent;
import org.primefaces.event.RowEditEvent;

import sun.reflect.ReflectionFactory.GetReflectionFactoryAction;
import unmsm.fisi.tesis.dao.HistoriaClinicaDAO;
import unmsm.fisi.tesis.dao.ReportesDAO;
import unmsm.fisi.tesis.entidad.Cromosoma;
import unmsm.fisi.tesis.entidad.Metricas;
import unmsm.fisi.tesis.servicio.ResultadoDiagnosticos;
import unmsm.fisi.tesis.si.AlgoritmoGenetico;
import unmsm.fisi.tesis.si.Carga;
import unmsm.fisi.tesis.si.FuncionFitness;

@ManagedBean(name = "diagnos")
@RequestScoped
public class DiagnosticarMB {
	
	private ResultadoDiagnosticos diagnostico;

	private List<ResultadoDiagnosticos> list;

	private String exactitudSistema2Medicos;
	private String sensibilidad2Medicos;
	private String especificidad2Medicos;
	
	private String exactitudSistema;
	private String sensibilidadSistema;
	private String especificidadSistema;
	
	private double prmaccS=0.0, promsenS=0.0, promspecS=0.0, promvppS=0.0, promvpnS=0.0;
	
	private String msjprmaccS="", msjpromsenS="", msjpromspecS="", msjpromvppS="", msjpromvpnS="";

	private double acc2M=0.0, sen2M=0.0, spec2M=0.0, vpp2M=0.0, vpn2M=0.0;
	
	private String msjacc2M="", msjsen2M="", msjspec2M="", msjvpp2M="", msjvpn2M="";
	
	private List<Metricas> metricas;

	public ResultadoDiagnosticos getDiagnostico() {
		return diagnostico;
	}

	public void setDiagnostico(ResultadoDiagnosticos diagnostico) {
		this.diagnostico = diagnostico;
	}

	private List<ResultadoDiagnosticos>  filteredList;

	
	public List<ResultadoDiagnosticos> getFilteredList() {
		return filteredList;
	}

	public void setFilteredList(List<ResultadoDiagnosticos> filteredList) {
		this.filteredList = filteredList;
	}

	public void diagnosticar(ActionEvent ae){
	    	
	    	AlgoritmoGenetico algoritmoGenetico = new AlgoritmoGenetico();
	    	Cromosoma cromosoma = algoritmoGenetico.obtenerUltimoCromosoma();
			
	    	int [][] EvaluacionPaciente = Carga.cargarHistoriasDePacientes(getDiagnostico().getNumeroHistoriaClinica(), "NO");
			
			FuncionFitness func = new FuncionFitness(1);
			func.setExperienciasPacientes(EvaluacionPaciente);
			int [] resultado = func.evaluacionDelSistemaUsandoLasOrganizaciones(cromosoma);
					
			new HistoriaClinicaDAO().modificarHistoriaResultadoSistema(getDiagnostico().getNumeroHistoriaClinica(),String.valueOf(resultado[0]));
			
			this.list = ReportesDAO.obtenerPacientesValidacion();
			
			calcularMetricas();
			
			String detalle = (resultado[0]>=1)? "Tiene SM ": "No Tiene SM ";
			
			
			FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "RESULTADO DEL DIAGNOSTICO: " +  detalle,  "Resultado del Diagnostico: " +  detalle);  
	        FacesContext.getCurrentInstance().addMessage("msj2", message);
	}
	
	public void cambiarMedico1Si(ActionEvent ae){
    	
		getDiagnostico().setS_diag_medico("SI");
				
		new HistoriaClinicaDAO().modificarHistoriaMedicos(getDiagnostico());
		
		this.list = ReportesDAO.obtenerPacientesValidacion();
		
		calcularMetricas();
		
		
		FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Modificacion Exitosa! " +  getDiagnostico().getNumeroHistoriaClinica(),  "Modificacion Exitosa! " +  getDiagnostico().getNumeroHistoriaClinica());  
        FacesContext.getCurrentInstance().addMessage("msj", message);
}
	
public void cambiarMedico1No(ActionEvent ae){
    	
		getDiagnostico().setS_diag_medico("NO");
				
		new HistoriaClinicaDAO().modificarHistoriaMedicos(getDiagnostico());
		
		this.list = ReportesDAO.obtenerPacientesValidacion();
		
		calcularMetricas();
		
		
		FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Modificacion Exitosa! " +  getDiagnostico().getNumeroHistoriaClinica(),  "Modificacion Exitosa! " +  getDiagnostico().getNumeroHistoriaClinica());  
        FacesContext.getCurrentInstance().addMessage("msj", message);
}

public void cambiarMedico2Si(ActionEvent ae){
	
	getDiagnostico().setS_diag_medico2("SI");
			
	new HistoriaClinicaDAO().modificarHistoriaMedicos(getDiagnostico());
	
	this.list = ReportesDAO.obtenerPacientesValidacion();
	
	calcularMetricas();
	
	
	FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Modificacion Exitosa! " +  getDiagnostico().getNumeroHistoriaClinica(),  "Modificacion Exitosa! " +  getDiagnostico().getNumeroHistoriaClinica());  
    FacesContext.getCurrentInstance().addMessage("msj", message);
}

public void cambiarMedico2No(ActionEvent ae){
	
	getDiagnostico().setS_diag_medico2("NO");
			
	new HistoriaClinicaDAO().modificarHistoriaMedicos(getDiagnostico());
	
	this.list = ReportesDAO.obtenerPacientesValidacion();
	
	calcularMetricas();
	
	
	FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Modificacion Exitosa! " +  getDiagnostico().getNumeroHistoriaClinica(),  "Modificacion Exitosa! " +  getDiagnostico().getNumeroHistoriaClinica());  
    FacesContext.getCurrentInstance().addMessage("msj", message);
}

	
	public List<ResultadoDiagnosticos> getList() {
		return list;
	}

	public void setList(List<ResultadoDiagnosticos> list) {
		this.list = list;
	}

	public DiagnosticarMB() {

		this.list = ReportesDAO.obtenerPacientesValidacion();
		
		calcularMetricas();
		
	}
	
	public void calcularMetricas(){
		
		int a1=0,b1=0,c1=0,d1=0;
		double acc1=0.0, sen1=0.0, spec1=0.0, vpp1=0.0, vpn1=0.0;
		
		int a2=0,b2=0,c2=0,d2=0;
		double acc2=0.0, sen2=0.0, spec2=0.0, vpp2=0.0, vpn2=0.0;
		
		int a3=0,b3=0,c3=0,d3=0;
		
		for(ResultadoDiagnosticos r:list){
			
			//medico y sistema
			if(r.getS_diag_medico().trim().equals("SI") && r.getS_diag_sistema().trim().equals("SI")){
			  a1++;
			}
			
			if(r.getS_diag_medico().trim().equals("NO") && r.getS_diag_sistema().trim().equals("SI")){
			  b1++;
			}
			
			if(r.getS_diag_medico().trim().equals("NO") && r.getS_diag_sistema().trim().equals("NO")){
			  d1++;
			}
			if(r.getS_diag_medico().trim().equals("SI") && r.getS_diag_sistema().trim().equals("NO")){
			  c1++;
			}
			
			//medico2 y sistema
			if(r.getS_diag_medico2().trim().equals("SI") && r.getS_diag_sistema().trim().equals("SI")){
				  a2++;
			}
				
			if(r.getS_diag_medico2().trim().equals("NO") && r.getS_diag_sistema().trim().equals("SI")){
				  b2++;
			}
				
			if(r.getS_diag_medico2().trim().equals("NO") && r.getS_diag_sistema().trim().equals("NO")){
				  d2++;
			}
			
			if(r.getS_diag_medico2().trim().equals("SI") && r.getS_diag_sistema().trim().equals("NO")){
				  c2++;
			}
			
			//dos medicos
			if(r.getS_diag_medico().trim().equals("SI") && r.getS_diag_medico2().trim().equals("SI")){
				  a3++;
			}
				
			if(r.getS_diag_medico().trim().equals("NO") && r.getS_diag_medico2().trim().equals("SI")){
				  b3++;
			}
				
			if(r.getS_diag_medico().trim().equals("NO") && r.getS_diag_medico2().trim().equals("NO")){
				  d3++;
			}
			
			if(r.getS_diag_medico().trim().equals("SI") && r.getS_diag_medico2().trim().equals("NO")){
				  c3++;
			}
		}
		
		//medico y sistema
		acc1 = (double)((a1 + d1)*100)/(a1+b1+c1+d1);
		sen1 = (double) a1*100/(a1+c1);
		spec1 = (double) d1*100/(b1+d1);
		
		vpp1 = (double) a1*100/(a1+b1);
		vpn1 = (double) d1*100/(c1+d1);
		
		//medico2 y sistema
		acc2 = (double) ((a2 + d2)*100)/(a2+b2+c2+d2);
		sen2 = (double) a2*100/(a2+c2);
		spec2 = (double) d2*100/(b2+d2);
		
		vpp2 = (double) a1*100/(a1+b1);
		vpn2 = (double) d1*100/(c1+d1);
		
		//SISDSM
		prmaccS = (acc1 + acc2)/2;
		promsenS = (sen1 + sen2)/2;
		promspecS = (spec1 + spec2)/2;
		promvppS = (vpp1 + vpp2)/2;
		promvpnS = (vpn1 + vpn2)/2;
		
		msjprmaccS = String.valueOf(  Math.round(prmaccS))+"%";
		msjpromsenS = String.valueOf(  Math.round(promsenS))+"%";
		msjpromspecS = String.valueOf(Math.round(promspecS))+"%";
		msjpromvppS = String.valueOf(Math.round(promvppS))+"%";
		msjpromvpnS = String.valueOf(Math.round(promvpnS))+"%";	
		
		//2 medicos
		acc2M = (double)((a3 + d3)*100)/(a3+b3+c3+d3);
		sen2M = (double) a3*100/(a3+c3);
		spec2M = (double) d3*100/(b3+d3);
		vpp2M = (double) a3*100/(a3+b3);
		vpn2M = (double) d3*100/(c3+d3);
		
		msjacc2M = String.valueOf(Math.round(acc2M))+"%";
		msjsen2M = String.valueOf(Math.round(sen2M))+"%";
		msjspec2M = String.valueOf(Math.round(spec2M))+"%";
		msjvpp2M = String.valueOf(Math.round(vpp2M))+"%";
		msjvpn2M = String.valueOf(Math.round(vpn2M))+"%";
		
		metricas = new ArrayList<Metricas>();
		metricas.add(new Metricas("Exactitud",msjacc2M, msjprmaccS));
		metricas.add(new Metricas("Sensibilidad",msjsen2M, msjpromsenS));
		metricas.add(new Metricas("Especificidad",msjspec2M, msjpromspecS));
		//metricas.add(new Metricas("Valor Predictivo Positivo ",msjvpp2M, msjpromvppS));
		//metricas.add(new Metricas("Valor Predictivo Negativo ",msjvpn2M, msjpromvpnS));
	}

	public String getExactitudSistema2Medicos() {
		return exactitudSistema2Medicos;
	}

	public void setExactitudSistema2Medicos(String exactitudSistema2Medicos) {
		this.exactitudSistema2Medicos = exactitudSistema2Medicos;
	}

	public String getSensibilidad2Medicos() {
		return sensibilidad2Medicos;
	}

	public void setSensibilidad2Medicos(String sensibilidad2Medicos) {
		this.sensibilidad2Medicos = sensibilidad2Medicos;
	}

	public String getEspecificidad2Medicos() {
		return especificidad2Medicos;
	}

	public void setEspecificidad2Medicos(String especificidad2Medicos) {
		this.especificidad2Medicos = especificidad2Medicos;
	}

	public String getExactitudSistema() {
		return exactitudSistema;
	}

	public void setExactitudSistema(String exactitudSistema) {
		this.exactitudSistema = exactitudSistema;
	}

	public String getSensibilidadSistema() {
		return sensibilidadSistema;
	}

	public void setSensibilidadSistema(String sensibilidadSistema) {
		this.sensibilidadSistema = sensibilidadSistema;
	}

	public String getEspecificidadSistema() {
		return especificidadSistema;
	}

	public void setEspecificidadSistema(String especificidadSistema) {
		this.especificidadSistema = especificidadSistema;
	}

	public double getPrmaccS() {
		return prmaccS;
	}

	public void setPrmaccS(double prmaccS) {
		this.prmaccS = prmaccS;
	}

	public double getPromsenS() {
		return promsenS;
	}

	public void setPromsenS(double promsenS) {
		this.promsenS = promsenS;
	}

	public double getPromspecS() {
		return promspecS;
	}

	public void setPromspecS(double promspecS) {
		this.promspecS = promspecS;
	}

	public double getAcc2M() {
		return acc2M;
	}

	public void setAcc2M(double acc2m) {
		acc2M = acc2m;
	}

	public double getSen2M() {
		return sen2M;
	}

	public void setSen2M(double sen2m) {
		sen2M = sen2m;
	}

	public double getSpec2M() {
		return spec2M;
	}

	public void setSpec2M(double spec2m) {
		spec2M = spec2m;
	}

	public String getMsjprmaccS() {
		return msjprmaccS;
	}

	public void setMsjprmaccS(String msjprmaccS) {
		this.msjprmaccS = msjprmaccS;
	}

	public String getMsjpromsenS() {
		return msjpromsenS;
	}

	public void setMsjpromsenS(String msjpromsenS) {
		this.msjpromsenS = msjpromsenS;
	}

	public String getMsjpromspecS() {
		return msjpromspecS;
	}

	public void setMsjpromspecS(String msjpromspecS) {
		this.msjpromspecS = msjpromspecS;
	}

	public String getMsjacc2M() {
		return msjacc2M;
	}

	public void setMsjacc2M(String msjacc2m) {
		msjacc2M = msjacc2m;
	}

	public String getMsjsen2M() {
		return msjsen2M;
	}

	public void setMsjsen2M(String msjsen2m) {
		msjsen2M = msjsen2m;
	}

	public String getMsjspec2M() {
		return msjspec2M;
	}

	public void setMsjspec2M(String msjspec2m) {
		msjspec2M = msjspec2m;
	}

	public List<Metricas> getMetricas() {
		return metricas;
	}

	public void setMetricas(List<Metricas> metricas) {
		this.metricas = metricas;
	}

	public double getPromvppS() {
		return promvppS;
	}

	public void setPromvppS(double promvppS) {
		this.promvppS = promvppS;
	}

	public double getPromvpnS() {
		return promvpnS;
	}

	public void setPromvpnS(double promvpnS) {
		this.promvpnS = promvpnS;
	}

	public String getMsjpromvppS() {
		return msjpromvppS;
	}

	public void setMsjpromvppS(String msjpromvppS) {
		this.msjpromvppS = msjpromvppS;
	}

	public String getMsjpromvpnS() {
		return msjpromvpnS;
	}

	public void setMsjpromvpnS(String msjpromvpnS) {
		this.msjpromvpnS = msjpromvpnS;
	}

	public double getVpp2M() {
		return vpp2M;
	}

	public void setVpp2M(double vpp2m) {
		vpp2M = vpp2m;
	}

	public double getVpn2M() {
		return vpn2M;
	}

	public void setVpn2M(double vpn2m) {
		vpn2M = vpn2m;
	}

	public String getMsjvpp2M() {
		return msjvpp2M;
	}

	public void setMsjvpp2M(String msjvpp2m) {
		msjvpp2M = msjvpp2m;
	}

	public String getMsjvpn2M() {
		return msjvpn2M;
	}

	public void setMsjvpn2M(String msjvpn2m) {
		msjvpn2M = msjvpn2m;
	}

}
